package com.db.gffxo.epi.format.type;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashMap;
import java.util.StringTokenizer;

import org.apache.log4j.Logger;

/**
 * Hello world!
 *
 */
public class EventFormatDetails 
{
	static Logger logger = Logger.getLogger(EventFormatDetails.class);
	private static SimpleDateFormat sdf1 = new SimpleDateFormat("MMM dd yyyy hh:mm:ss");
	
	private String protocol = null;
	private String deviceVendor = null;
	private String deviceProduct = null;
	private String deviceVersion = null;
	private String signatureId = null;
	private String name = null;
	private String priority = null;
	private String mandatoryFields = null;
	private String optionalFields = null;
	private HashMap manKeyValuePairs = null;
	private HashMap optKeyValuePairs = null;
	private String msgTemplate = null;
	
	
	
	public void prepareMsgTemplate() {
		StringBuffer msgTemplate = new StringBuffer();
		msgTemplate.append(getProtocol());
		msgTemplate.append("|");
		msgTemplate.append(getDeviceVendor());
		msgTemplate.append("|");
		msgTemplate.append(getDeviceProduct());
		msgTemplate.append("|");
		msgTemplate.append(getDeviceVersion());
		msgTemplate.append("|");
		
		// TODO - Should these be parameterized so one definition can handle multiple types?
		msgTemplate.append(getSignatureId());
		msgTemplate.append("|");
		msgTemplate.append(getName());
		msgTemplate.append("|");
		msgTemplate.append(getPriority());
		msgTemplate.append("|");
		
		setMsgTemplate(msgTemplate.toString());
	}
	
	
	public String formatMessage(HashMap<String,String> values) {
		
		if (getMsgTemplate()==null)
			prepareMsgTemplate();
		
		// First the mandatory fields
		StringBuffer message = new StringBuffer(getMsgTemplate());
		StringTokenizer tk = new StringTokenizer(getMandatoryFields(),",");
		String key = null;
		String value = null;
		while (tk.hasMoreElements()){
			key=tk.nextToken();
			value=getManKeyValuePairs().get(key);
			if (value.startsWith("{")) {
				String dataKey=value.substring(1,value.length()-1);
				value = values.get(dataKey);
			}
		
			//TODO - Need to create proper exception handling here.
			if (value==null)
				throw new RuntimeException("MissingMandatoryValue");
			
			if (value.endsWith("()")) {
				value = evaluateFunction(value);
			}
			message.append(key);
			message.append("=");
			message.append(value);
			message.append(" ");
			//Add evaluated variable to values to be used again in message
			values.put(key, value);
		}
		
		// Now the optional ones
		tk = new StringTokenizer(getOptionalFields(),",");
		while (tk.hasMoreElements()){
			key=tk.nextToken();
			value=getOptKeyValuePairs().get(key);
			if (value.startsWith("{")) 
				value = values.get(key);
			
			if (!(value==null)) {

				if (value.endsWith("()")) {
					value = evaluateFunction(value);
				}
				message.append(key);
				message.append("=");
				message.append(value);
				message.append(" ");
				//Add evaluated variable to values to be used again in message
				values.put(key, value);
			}			
		}		
		return message.toString();		
	}
	
	public String evaluateFunction (String function) {
		// now () - provides the current date and time in the standard format.
		// TODO - Need to determine if dates are required in a specific time zone.
		if (function.equals("now()")) {
			String now = sdf1.format(Calendar.getInstance().getTime());
			return now;
		}
		
		
		return function;
	}
	
	
	public String getProtocol() {
		return protocol;
	}
	public void setProtocol(String protocol) {
		this.protocol = protocol;
	}
	public String getDeviceVendor() {
		return deviceVendor;
	}
	public void setDeviceVendor(String deviceVendor) {
		this.deviceVendor = deviceVendor;
	}
	public String getDeviceProduct() {
		return deviceProduct;
	}
	public void setDeviceProduct(String deviceProduct) {
		this.deviceProduct = deviceProduct;
	}
	public String getDeviceVersion() {
		return deviceVersion;
	}
	public void setDeviceVersion(String deviceVersion) {
		this.deviceVersion = deviceVersion;
	}
	public String getSignatureId() {
		return signatureId;
	}
	public void setSignatureId(String signatureId) {
		this.signatureId = signatureId;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getPriority() {
		return priority;
	}
	public void setPriority(String priority) {
		this.priority = priority;
	}
	public HashMap<String,String> getManKeyValuePairs() {
		return manKeyValuePairs;
	}
	public void setManKeyValuePairs(HashMap<String,String> keyValuePairs) {
		this.manKeyValuePairs = keyValuePairs;
	}
	public HashMap<String,String> getOptKeyValuePairs() {
		return optKeyValuePairs;
	}
	public void setOptKeyValuePairs(HashMap<String,String> keyValuePairs) {
		this.optKeyValuePairs = keyValuePairs;
	}
	public String getMsgTemplate() {
		return msgTemplate;
	}
	public void setMsgTemplate(String msgTemplate) {
		this.msgTemplate = msgTemplate;
	}

	public String getMandatoryFields() {
		return mandatoryFields;
	}

	public void setMandatoryFields(String mandatoryFields) {
		this.mandatoryFields = mandatoryFields;
	}

	public String getOptionalFields() {
		return optionalFields;
	}

	public void setOptionalFields(String optionalFields) {
		this.optionalFields = optionalFields;
	}
	

}
